﻿namespace TestTool.GUI.Utils
{
    using System;
    using System.Net;
    using System.Runtime.CompilerServices;
    using System.ServiceModel;
    using System.ServiceModel.Channels;
    using TestTool.Proxies.Onvif;
    using TestTool.Tests.Common.TestBase;

    internal class ManagementServiceProvider : BaseServiceProvider<DeviceClient, Device>
    {
        public event CapabilitiesReceived OnCapabilitiesReceived;

        public event DeviceInformationReceived OnDeviceInformationReceived;

        public event ServicesInfoReceived OnServicesInfoReceived;

        public ManagementServiceProvider(string serviceAddress, int messageTimeout) : base(serviceAddress, messageTimeout)
        {
            base.EnableLogResponse = true;
        }

        public override DeviceClient CreateClient(Binding binding, EndpointAddress address)
        {
            return new DeviceClient(binding, address);
        }

        public void GetCapabilities(CapabilityCategory[] capabilities)
        {
            base.RunInBackground(delegate {
                Capabilities capabilities1 = this.Client.GetCapabilities(capabilities);
                if (this.OnCapabilitiesReceived != null)
                {
                    this.OnCapabilitiesReceived(capabilities1);
                }
            });
        }

        public DeviceServicesInfo GetCapabilitiesDefineSecurity(CapabilityCategory[] categories)
        {
            DeviceServicesInfo info = new DeviceServicesInfo();
            Capabilities capabilities = null;
            Service[] services = null;
            bool getServicesNotSupported = false;
            base.ConstructSecurityTolerantAction(delegate {
                if (!getServicesNotSupported)
                {
                    try
                    {
                        services = this.Client.GetServices(false);
                        return;
                    }
                    catch (FaultException exception)
                    {
                        if (exception.IsValidOnvifFault("Sender/NotAuthorized") || exception.IsValidOnvifFault("Sender/NotAuthorized/SenderNotAuthorized"))
                        {
                            throw exception;
                        }
                        if (exception.IsValidOnvifFault("Receiver/ActionNotSupported/NoSuchService"))
                        {
                            getServicesNotSupported = true;
                        }
                    }
                }
                try
                {
                    if (services == null)
                    {
                        capabilities = this.Client.GetCapabilities(categories);
                    }
                }
                catch (FaultException exception2)
                {
                    if (exception2.IsValidOnvifFault("Sender/NotAuthorized") || exception2.IsValidOnvifFault("Sender/NotAuthorized/SenderNotAuthorized"))
                    {
                        throw exception2;
                    }
                }
            })();
            info.Capabilities = capabilities;
            info.Services = services;
            return info;
        }

        public void GetDeviceInformation()
        {
            base.RunInBackground(new Action(this.GetDeviceInformationInternal));
        }

        public void GetDeviceInformationEx()
        {
            Action action = base.ConstructSecurityTolerantAction(() => this.GetDeviceInformationInternal());
            base.RunInBackground(action);
        }

        private void GetDeviceInformationInternal()
        {
            string str;
            string str3;
            string str4;
            string str5;
            string manufacturer = base.Client.GetDeviceInformation(out str, out str5, out str4, out str3);
            if (this.OnDeviceInformationReceived != null)
            {
                this.OnDeviceInformationReceived(manufacturer, str, str5, str4, str3);
            }
        }

        public void GetHostname()
        {
            base.RunInBackground(() => base.Client.GetHostname());
        }

        public void GetInterfaces()
        {
            base.RunInBackground(() => base.Client.GetNetworkInterfaces());
        }

        public void GetScopes()
        {
            base.RunInBackground(() => base.Client.GetScopes());
        }

        public void GetServiceAddresses(bool capabilitiesStyle, CapabilityCategory[] categories)
        {
            base.RunInBackground(delegate {
                Capabilities capabilities = null;
                Service[] services = null;
                if (capabilitiesStyle)
                {
                    capabilities = this.Client.GetCapabilities(categories);
                }
                else
                {
                    services = this.Client.GetServices(false);
                }
                if (this.OnServicesInfoReceived != null)
                {
                    this.OnServicesInfoReceived(capabilities, services);
                }
            });
        }

        public void GetServices()
        {
            base.RunInBackground(() => base.Client.GetServices(true));
        }

        public void HardReset()
        {
            base.RunInBackground(() => base.Client.SetSystemFactoryDefault(FactoryDefaultType.Hard));
        }

        public void Reboot()
        {
            base.RunInBackground(() => base.Client.SystemReboot());
        }

        public void SetGateway(string gateway)
        {
            base.RunInBackground(delegate {
                System.Net.IPAddress address = System.Net.IPAddress.Parse(gateway);
                string[] strArray = null;
                string[] strArray2 = null;
                if (address.GetAddressBytes().Length == 4)
                {
                    strArray = new string[] { gateway };
                }
                else
                {
                    strArray2 = new string[] { gateway };
                }
                this.Client.SetNetworkDefaultGateway(strArray, strArray2);
            });
        }

        public void SetIPAddress(string token, string address, int prefixLength)
        {
            base.RunInBackground(() => this.SetIPInternal(token, address, prefixLength));
        }

        private void SetIPInternal(string token, string ip, int prefix)
        {
            NetworkInterface[] networkInterfaces;
            base.EnableLogResponse = false;
            try
            {
                networkInterfaces = base.Client.GetNetworkInterfaces();
            }
            catch (Exception exception)
            {
                base.ReportException(exception, "An exception was thrown during getting network interface: ");
                base.ReportOperationCompleted();
                return;
            }
            finally
            {
                base.EnableLogResponse = true;
            }
            foreach (NetworkInterface interface2 in networkInterfaces)
            {
                if (interface2.token == token)
                {
                    PrefixedIPv4Address address = new PrefixedIPv4Address {
                        Address = ip,
                        PrefixLength = prefix
                    };
                    NetworkInterfaceSetConfiguration networkInterface = new NetworkInterfaceSetConfiguration {
                        IPv4 = new IPv4NetworkInterfaceSetConfiguration()
                    };
                    networkInterface.IPv4.DHCP = false;
                    networkInterface.IPv4.DHCPSpecified = false;
                    networkInterface.IPv4.Enabled = true;
                    networkInterface.IPv4.EnabledSpecified = true;
                    networkInterface.IPv4.Manual = new PrefixedIPv4Address[] { address };
                    networkInterface.MTU = interface2.Info.MTU;
                    networkInterface.MTUSpecified = true;
                    networkInterface.Link = interface2.Link.AdminSettings;
                    networkInterface.Enabled = true;
                    networkInterface.EnabledSpecified = true;
                    base.Client.SetNetworkInterfaces(token, networkInterface);
                    return;
                }
            }
            throw new Exception(string.Format("Network interface matching Token \"{0}\" not found", token));
        }

        public void SyncTime()
        {
            base.RunInBackground(delegate {
                SystemDateTime systemDateAndTime = base.Client.GetSystemDateAndTime();
                System.DateTime time2 = System.DateTime.Now.ToUniversalTime();
                TestTool.Proxies.Onvif.DateTime uTCDateTime = new TestTool.Proxies.Onvif.DateTime {
                    Date = new Date(),
                    Time = new Time()
                };
                uTCDateTime.Date.Year = time2.Year;
                uTCDateTime.Date.Month = time2.Month;
                uTCDateTime.Date.Day = time2.Day;
                uTCDateTime.Time.Hour = time2.Hour;
                uTCDateTime.Time.Minute = time2.Minute;
                uTCDateTime.Time.Second = time2.Second;
                base.Client.SetSystemDateAndTime(SetDateTimeType.Manual, systemDateAndTime.DaylightSavings, null, uTCDateTime);
            });
        }

        public delegate void CapabilitiesReceived(Capabilities capabilities);

        public delegate void DeviceInformationReceived(string manufacturer, string model, string firmwareVersion, string serial, string hardwareId);

        public delegate void ServicesInfoReceived(Capabilities capabilities, Service[] services);
    }
}

